package ntd.remote.link;

import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.task.Task;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import lj.a.protocol.lj.bean.LJProtocolInfo;
import lj.netty.ToolNettyInit;
import lj.netty.bean.LJNettyBo;
import lj.netty.bean.LJNettyInitContext;
import lj.netty.bean.LJNettyMsgContext;
import lj.netty.listen.LJNettyListen;
import ntd.action.ActionManager;
import ntd.action.bo.ActionInBo;
import ntd.action.bo.ActionInfo;
import ntd.action.bo.ActionOutBo;
import ntd.remote.link.bo.MsgBO;
import ntd.remote.link.bo.RemoteBO;
import ntd.util.UtilRun;

public class ComRegistryClient {

    public static LJNettyInitContext ljNettyInitContext;

    public static LJNettyListen ljNettyListen;

    private static String scheduleId;

    private static void init(RemoteBO remoteBO) {
        UtilRun.onlyOne("link-client-init", () -> {
            ljNettyInitContext = new LJNettyInitContext()
                    .setPort(remoteBO.getPort())
                    .setHost(remoteBO.getServerIp())
                    .setTerminalCode(remoteBO.getTerminalCode())
                    .setLJCNettyListen(ljNettyListen = new LJNettyListen() {
                        @Override
                        public byte[] onLjMsg(LJNettyMsgContext ljNettyMsgContext) {
                            return remoteBO.getFunIn().accept(MsgBO.transform(ljNettyMsgContext));
                        }
                        @Override
                        public void onInit(LJNettyBo LJNettyBo) {
                            register(remoteBO);
                        }
                    });

            new ToolNettyInit(ljNettyInitContext).start();
        });
    }

    private static void heartbeatPacket() {
        Opt.ofBlankAble(scheduleId).ifPresent(CronUtil::remove);
        scheduleId = CronUtil.schedule("0 * * * * *", (Task) () -> {
            MsgBO msgBO = new MsgBO();
            msgBO.setActionCode(ActionHeartbeatPacket.ACTION_NETTY_HEARTBEAT_PACKET);
            msgBO.setData(ljNettyInitContext.getTerminalCode());
            msgBO.setTerminalCode(ljNettyInitContext.getTerminalCode());
            ljNettyListen.pushMsgAll(new LJProtocolInfo().setData(JSONUtil.toJsonStr(msgBO).getBytes()));
        });
    }

    private static void register(RemoteBO remoteBO) {
        MsgBO msgBO = new MsgBO();
        msgBO.setActionCode(ActionRemoteRegister.ACTION_REMOTE_REGISTER);
        msgBO.setData(remoteBO.getTerminalName());
        msgBO.setTerminalCode(ljNettyInitContext.getTerminalCode());
        ljNettyListen.pushMsgAll(new LJProtocolInfo().setData(JSONUtil.toJsonStr(msgBO).getBytes()));
        StaticLog.info("注册本机[{}]到注册中心成功", remoteBO.getTerminalName());

//        registerAction(remoteBO);
    }

    private static void registerAction(RemoteBO remoteBO) {
        MsgBO msgBO = new MsgBO();
        msgBO.setActionCode(ActionRemoteRegisterAction.ACTION_REMOTE_REGISTER_ACTION);
        msgBO.setData(JSONUtil.toJsonStr(ActionManager.list()));
        msgBO.setTerminalCode(ljNettyInitContext.getTerminalCode());
        ljNettyListen.pushMsgAll(new LJProtocolInfo().setData(JSONUtil.toJsonStr(msgBO).getBytes()));
        StaticLog.info("注册本机[{}]能力到注册中心成功", remoteBO.getTerminalName());
        heartbeatPacket();
    }

    public static LJNettyMsgContext sendMsg(MsgBO msgBO) {
        Opt.ofBlankAble(ljNettyInitContext.getTerminalCode()).ifPresent(msgBO::setTerminalCode);
        LJProtocolInfo ljProtocolInfo = new LJProtocolInfo();
        ljProtocolInfo.setBytes(msgBO.getBytes());
        msgBO.setBytes(new byte[]{});
        ljProtocolInfo.setData(JSONUtil.toJsonStr(msgBO).getBytes());
        return ljNettyListen.pushMsgAll(ljProtocolInfo);
    }

    public static void main(String[] args) {
        ThreadUtil.execAsync(() -> run("client-ai-server", "AI客户端", "61.52.247.249", 13021));

//        ComRemoteFileBO comRemoteFileBO = new ComRemoteFileBO();
//        comRemoteFileBO.setPath("D:\\AI_result\\person_json\\20230608\\Person-20230608-20230608115103623v0pxtb5ikt98bmr\\17302654901-520d0388201b4593866cf34540d101ef-20230608115046-Person-image.json");
////            comRemoteFileBO.setPath("D:\\ai-server-async-file-path");
//        comRemoteFileBO.setRemoteCode("client-ai-server");
//        byte[] bytes = ComRemoteFile.me.readFile(comRemoteFileBO);
//        StaticLog.info(new String(bytes, StandardCharsets.UTF_8));
//        StaticLog.info("执行完成...");

//        run("测试客户端", "115.29.192.252");

//        ThreadUtil.sleep(10000);
//        ComRemoteFileBO comRemoteFileBO = new ComRemoteFileBO();
//        comRemoteFileBO.setPath("D:\\test\\test.txt");
//
//        byte[] bytes = new byte[1024 * 12000];
//        comRemoteFileBO.setStream(bytes);
//        comRemoteFileBO.setRemoteCode("client-ai-test");
//        StaticLog.info("文件添加开始");
//        ComRemoteFile.me.add(comRemoteFileBO);
//        StaticLog.info("文件添加完成");
    }

    public static void run(String terminalCode, String terminalName, String serverIp, int port) {
        RemoteBO remoteBO = new RemoteBO();

        remoteBO.setTerminalName(terminalName);
        remoteBO.setServerIp(serverIp);
        remoteBO.setTerminalCode(terminalCode);
        remoteBO.setPort(port);

        remoteBO.setFunIn(msgBO -> {
            ActionInfo actionInfo = ActionManager.get(msgBO.getActionCode());
            ActionOutBo actionOutBo = actionInfo.getAction().execute(new ActionInBo().setData(Dict.parse(msgBO)));
            return actionOutBo.toBytes();
        });
        ComRegistryClient.init(remoteBO);
    }
}
